package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.vo.OrderReportVO;
import com.sky.vo.SalesTop10ReportVO;
import com.sky.vo.TurnoverReportVO;
import com.sky.vo.UserReportVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: XJH
 * @Description: TODO
 * @Date: 2025/6/11 12:01
 * @Version: 1.0
 */
@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    /**
     * 营业额统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    // TODO: 2025/6/11 为啥要封装map对象 ，是不是太麻烦了，和模糊查询又有什么关系，对数据库造成多查又有什么影响
    public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) {
        // 修复：正确生成日期范围（包含begin，不包含end）
        // 存放从begin到end范围内的每天的日期
        List<LocalDate> dateList = new ArrayList<>();
        LocalDate current = begin;
        while (current.isBefore(end)) {
            dateList.add(current);
            current = current.plusDays(1);
        }

        //  存放从begin到end范围内的每天的营业额
        List<Double> turnoverList = new ArrayList<>();
        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);

         // 查询每天营业额
            Map<String, Object> map = new HashMap<>();
            map.put("begin", beginTime);
            map.put("end", endTime);
            map.put("status", 5); // 已完成订单

            Double turnover = orderMapper.sumByMap(map);
            turnoverList.add(turnover == null ? 0.0 : turnover);
        }

        return TurnoverReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .turnoverList(StringUtils.join(turnoverList, ","))
                .build();
    }
    /**
     * 用户统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
        //当前集合用于存放从begin到end范围内的每天的日期
        List<LocalDate> dateList = new ArrayList<>();
        while(!begin.equals(end)) {
            begin=begin.plusDays(1);
            dateList.add(begin);

        }
        //存放每天的新用户数
        //select count(*) from user where create_time > begin and create_time < end
        List<Integer> newUserList = new ArrayList<>();
        // 存放每天总用户数
        //select count(*) from user where  create_time < ?

        List<Integer> totalUserList = new ArrayList<>();
        for(LocalDate date:dateList)
        {
            //一天
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            HashMap map = new HashMap<>();
            map.put("end",endTime);
            //查询date日期对应的总用户数
            Integer totalUsers = userMapper.countByMap(map);
            map.put("begin",beginTime);
            //查询date日期对应的新用户数
            Integer newUsers = userMapper.countByMap(map);
            newUserList.add(newUsers);
            totalUserList.add(totalUsers);
        }
        return UserReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .newUserList(StringUtils.join(newUserList, ","))
                .totalUserList(StringUtils.join(totalUserList, ","))
                .build();

    }
    /**
     * 订单统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    //查询订单总数时，map 包含 begin 和 end
    //查询有效订单数时，map 添加了 status=5
    //第二次循环时，map 仍然包含 status=5，这会导致查询订单总数时也包含了 status=5 的条件，从而使每日订单数都相同
    //这就是为什么每日订单数和有效订单数都是固定值的原因。
    public OrderReportVO getOrdersStatistics(LocalDate begin, LocalDate end) {
//        // 当前集合用于存放从begin到end范围内的每天的日期
//        List<LocalDate> dateList = new ArrayList<>();
//        LocalDate current = begin;
//        while (!current.isAfter(end)) {
//            dateList.add(current);
//            current = current.plusDays(1);
//        }
//
//        // 每日订单数（明确泛型）
//        List<Integer> orderCountList = new ArrayList<>();
//        // 每日有效订单数（明确泛型）
//        List<Integer> validOrderCountList = new ArrayList<>();
//
//        for (LocalDate date : dateList) {
//            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
//            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
//
//            // 1. 查询订单总数（独立Map，无状态过滤）
//            Map<String, Object> totalMap = new HashMap<>();
//            totalMap.put("begin", beginTime);
//            totalMap.put("end", endTime);
//            Integer orderCount = orderMapper.countByMap(totalMap);
//            orderCountList.add(orderCount == null ? 0 : orderCount);
//
//            // 2. 查询有效订单数（独立Map，包含状态过滤）
//            Map<String, Object> validMap = new HashMap<>();
//            validMap.put("begin", beginTime);
//            validMap.put("end", endTime);
//            validMap.put("status", 5);
//            Integer validOrderCount = orderMapper.countByMap(validMap);
//            validOrderCountList.add(validOrderCount == null ? 0 : validOrderCount);
//        }
//
//        // 计算时间区间内的订单总数量（处理空值）
//        Integer totalOrderCount = orderCountList.stream()
//                .reduce(Integer::sum)
//                .orElse(0);
//
//        // 计算时间区间内的有效订单数量（处理空值）
//        Integer validOrderTotal = validOrderCountList.stream()
//                .reduce(Integer::sum)
//                .orElse(0);
//
//        // 计算订单完成率（避免除以0）
//        Double orderCompletionRate = totalOrderCount == 0 ? 0.0 : (double) validOrderTotal / totalOrderCount;
//
//        return OrderReportVO.builder()
//                .dateList(StringUtils.join(dateList, ","))
//                .orderCountList(StringUtils.join(orderCountList, ","))
//                .validOrderCountList(StringUtils.join(validOrderCountList, ","))
//                .totalOrderCount(totalOrderCount)
//                .validOrderCount(validOrderTotal)
//                .orderCompletionRate(orderCompletionRate)
//                .build();

        // 构造查询时间范围
        // 生成完整日期列表
        List<LocalDate> dateList = new ArrayList<>();
        LocalDate current = begin;
        while (!current.isAfter(end)) {
            dateList.add(current);
            current = current.plusDays(1);
        }

        // 构造查询参数
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);

        // 一次查询获取所有天的订单数据
        List<Map<String, Object>> OrderForAllDays = orderMapper.getDailyOrderStats(beginTime, endTime);

        // 整理每日订单数和有效订单数
        List<Integer> orderCountList = new ArrayList<>();
        List<Integer> validOrderCountList = new ArrayList<>();

        for (LocalDate date : dateList) {
            Integer totalOrderCount = 0;
            Integer validOrderCount = 0;

            for (Map<String, Object> stats : OrderForAllDays) {
                // 安全转换orderDate为LocalDate
                Object orderDateObj = stats.get("orderDate");
                if (orderDateObj instanceof String) {
                    LocalDate dbDate = LocalDate.parse((String) orderDateObj);
                    if (dbDate.equals(date)) {
                        totalOrderCount = ((Number) stats.get("totalCount")).intValue();
                        validOrderCount = ((Number) stats.get("validCount")).intValue();
                        break;
                    }
                } else if (orderDateObj instanceof java.sql.Date) {
                    LocalDate dbDate = ((java.sql.Date) orderDateObj).toLocalDate();
                    if (dbDate.equals(date)) {
                        totalOrderCount = ((Number) stats.get("totalCount")).intValue();
                        validOrderCount = ((Number) stats.get("validCount")).intValue();
                        break;
                    }
                }
            }

            orderCountList.add(totalOrderCount);
            validOrderCountList.add(validOrderCount);
        }

        // 计算汇总数据
        Integer totalOrderCount = orderCountList.stream().reduce(Integer::sum).orElse(0);
        Integer validOrderTotal = validOrderCountList.stream().reduce(Integer::sum).orElse(0);
        Double orderCompletionRate = totalOrderCount == 0 ? 0.0 : (double) validOrderTotal / totalOrderCount;

        return OrderReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .orderCountList(StringUtils.join(orderCountList, ","))
                .validOrderCountList(StringUtils.join(validOrderCountList, ","))
                .totalOrderCount(totalOrderCount)
                .validOrderCount(validOrderTotal)
                .orderCompletionRate(orderCompletionRate)
                .build();
    }
    /**
     * 查询销量top10
     * @param begin
     * @param end
     * @return
     */
    @Override
    public SalesTop10ReportVO getTop10(LocalDate begin, LocalDate end) {
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        List<GoodsSalesDTO> salesTop10 = orderMapper.getSalesTop10(beginTime, endTime);
        List<String> namelist = salesTop10.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
        String names = StringUtils.join(namelist, ",");
        List<Integer> numberlist = salesTop10.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());
        String numbers = StringUtils.join(numberlist, ",");
        return SalesTop10ReportVO.builder()
                .nameList(names)
                .numberList(numbers)
                .build();
    }
    }

